package com.memory.monitor.aop;

import com.alibaba.fastjson.JSONObject;
import com.memory.monitor.model.entity.Log;
import com.memory.monitor.model.entity.User;
import com.memory.monitor.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Arrays;

@Component
@Aspect
@Slf4j
public class LogAspect {
    @Resource
    private UserService userService;

    @Around("@annotation(com.memory.monitor.annotation.LogInformation)")
    public Object recordLog(ProceedingJoinPoint joinPoint) throws Throwable {
        // 封装日志信息
        Log logInfo = new Log();
        RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        User loginUser = userService.getLoginUser(request);

        logInfo.setId(loginUser.getId());
        logInfo.setOperateUser(loginUser.getUserName());
        logInfo.setOperateTime(LocalDateTime.now());
        logInfo.setClassName(joinPoint.getTarget().getClass().getName());
        logInfo.setMethodName(joinPoint.getSignature().getName());
        logInfo.setMethodParams(Arrays.toString(joinPoint.getArgs()));

        long startTime = System.currentTimeMillis();
        Object result = joinPoint.proceed();
        long endTime = System.currentTimeMillis();

        String jsonString = JSONObject.toJSONString(result);
        logInfo.setReturnValue(jsonString);
        logInfo.setCostTime(endTime - startTime);

        log.info("aop记录的日志信息：" + logInfo);

        return result;
    }
}
